package com.aiti.lulian.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.controller.WebController;
import com.aiti.base.core.constant.MessageCodeConstant;
import com.aiti.base.core.utils.message.Message;
import com.aiti.lulian.dto.ProductNewInfoDto;
import com.aiti.lulian.dto.ShowActivityInfoDto;
import com.aiti.lulian.dto.ShowActivityInfoEnrollDto;
import com.aiti.lulian.dto.ShowActivityInfoExportDto;
import com.aiti.lulian.entity.ProductNew;
import com.aiti.lulian.entity.ShowActivityInfo;
import com.aiti.lulian.entity.ShowActivityInfoEnroll;
import com.aiti.lulian.entity.SysArea;
import com.aiti.lulian.feign.CloudShowManagerSubService;
import com.aiti.lulian.handler.HeaderStyleHandler;
import com.aiti.lulian.service.ISysAreaService;
import com.aiti.lulian.service.ShowActivityInfoEnrollService;
import com.aiti.lulian.service.ShowActivityInfoService;
import com.aiti.lulian.vo.CommunicateInfoExportVo;
import com.aiti.lulian.vo.ShowActivityInfoEnrollVo;
import com.aiti.lulian.vo.ShowActivityInfoVo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.net.HttpHeaders;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.aiti.lulian.dto.ShowActivityInfoImportDto;

/**
 * <p>
 * 活动 前端控制器
 * </p>
 *
 * @author 
 * @since
 */
@RestController
@RequestMapping("/activityInfo")
public class ShowActivityInfoController extends WebController {
    @Autowired
    private ShowActivityInfoService activityInfoService;
    @Autowired
    private CloudShowManagerSubService managerSubService;
    @Autowired
    private ISysAreaService areaService;
    @Autowired
    private ShowActivityInfoEnrollService activityInfoEnrollService;


    @GetMapping("/addInternal")
    public Message addInternal() {
        return activityInfoService.internalAddEShow365Activity();
    }

    @GetMapping("/addAbroad")
    public Message addAbroad() {
        return activityInfoService.abroadAddEShow365Activity();
    }

    @GetMapping("/detail")
    public Message detail(@RequestParam("baseId") String baseId, @RequestParam(value="userId",required = false) String userId) {
        ShowActivityInfo activityInfo = activityInfoService.getActivityById(baseId);
        if(!StringUtils.isEmpty(userId)){
            List<ShowActivityInfoEnroll> list = activityInfoEnrollService.list(new LambdaQueryWrapper<ShowActivityInfoEnroll>().eq(ShowActivityInfoEnroll::getCreator, userId).eq(ShowActivityInfoEnroll::getActivityId, baseId));
            if(list.size() > 0){
                activityInfo.setUserEnrollFlag(true);
            }

        }
        return Message.success(activityInfo);
    }

    @PostMapping
    public Message insert(@RequestBody ShowActivityInfo entity) {
        entity.setCreator(findUserId());
        entity.setSource("0");
        activityInfoService.saveActivity(entity);
        return Message.success();
    }

    @PutMapping
    public Message update(@RequestBody ShowActivityInfo entity) {
        entity.setUpdateBy(findUserId());
        activityInfoService.updateActivity(entity);
        return Message.success();
    }

    @DeleteMapping
    public Message delete(@RequestParam("baseId") String baseId) {
        activityInfoService.deleteActivity(baseId);
        return Message.success();
    }

    @GetMapping("/page")
    public Message page(ShowActivityInfoDto dto) {
        Page page = this.startPage(dto);
        List<ShowActivityInfoVo> list = activityInfoService.listActivities(page, dto);
        return Message.success(this.getPageResult(list, (int)page.getTotal()));
    }

    @GetMapping("/webPage")
    public Message webPage(ShowActivityInfoDto dto) {
        List<String> userRoleList = managerSubService.getUserRoleList(findUserId());
        if(CollectionUtils.isEmpty(userRoleList) || !userRoleList.contains("1")){
            Message userInfo = managerSubService.getUserInfo(findUserId());
            if(userInfo != null && userInfo.getCode() == MessageCodeConstant.MSG_SUCCESS_CODE){
                Map obj = (Map)userInfo.getObj();
                dto.setCity(String.valueOf(obj.get("city")));
                dto.setCounty(String.valueOf(obj.get("region")));
                dto.setStreet(String.valueOf(obj.get("street")));
            }else{
                throw new RuntimeException("获取用户信息有误");
            }
        }
        Page page = this.startPage(dto);
        dto.setSource("0");
        List<ShowActivityInfoVo> list = activityInfoService.listActivities(page, dto);
        return Message.success(this.getPageResult(list, (int)page.getTotal()));
    }

    @ApiOperation(value = "导入活动")
    @PostMapping("importData")
    @Transactional(rollbackFor = Exception.class)
    public Message importData(@RequestPart("file") MultipartFile file) throws IOException {
        String userId = findUserId();
        List<ShowActivityInfo> activityList = new ArrayList();
        List<SysArea> cityAreaList = areaService.list(new QueryWrapper<SysArea>().eq("area_level", "2").isNotNull("base_parent_id"));
        Map<String, String> cityMap = new HashMap();
        Map<String, String> countyMap = new HashMap();
        Map<String, String> streetMap = new HashMap();
        if(!CollectionUtils.isEmpty(cityAreaList)){
            cityMap = cityAreaList.stream().collect(Collectors.toMap(k -> k.getBaseName(), v -> v.getBaseId(), (oldVal, newVal) -> oldVal));
        }
        List<SysArea> countyAreaList = areaService.list(new QueryWrapper<SysArea>().eq("area_level", "3").isNotNull("base_parent_id"));
        if(!CollectionUtils.isEmpty(countyAreaList)){
            countyMap = countyAreaList.stream().collect(Collectors.toMap(k -> k.getBaseName(), v -> v.getBaseId(), (oldVal, newVal) -> oldVal));
        }

        List<SysArea> streetAreaList = areaService.list(new QueryWrapper<SysArea>().eq("area_level", "4").isNotNull("base_parent_id"));
        if(!CollectionUtils.isEmpty(streetAreaList)){
            streetMap = streetAreaList.stream().collect(Collectors.toMap(k -> k.getBaseName(), v -> v.getBaseId(), (oldVal, newVal) -> oldVal));
        }

        Map<String, String> finalCityMap = cityMap;
        Map<String, String> finalCountyMap = countyMap;
        Map<String, String> finalStreetMap = countyMap;
        EasyExcel.read(file.getInputStream(), ShowActivityInfoImportDto.class, new ReadListener<ShowActivityInfoImportDto>(){

            @Override
            public void invoke(ShowActivityInfoImportDto importData, AnalysisContext analysisContext) {
                ShowActivityInfo activity = new ShowActivityInfo();
                String city = importData.getCity();
                String county = importData.getCounty();
                String street = importData.getStreet();
                activity.setProvince("F2557678-A421-4E33-9F18-B93FDB3C86DC");
                if(!org.springframework.util.StringUtils.isEmpty(city)){
                    if(finalCityMap.containsKey(city)){
                        importData.setCity(finalCityMap.get(city));
                    }else{
                        List<SysArea> areaCode = areaService.list(new QueryWrapper<SysArea>().likeRight("base_name", city).eq("area_level", "2").isNotNull("base_parent_id"));
                        if(!CollectionUtils.isEmpty(areaCode)){
                            importData.setCity(areaCode.get(0).getBaseId());
                        }
                    }
                }
                if(!org.springframework.util.StringUtils.isEmpty(county)){
                    if(finalCityMap.containsKey(county)){
                        importData.setCounty(finalCountyMap.get(county));
                    }else{
                        List<SysArea> areaCode = areaService.list(new QueryWrapper<SysArea>().likeRight("base_name", county).eq("area_level", "3").isNotNull("base_parent_id"));
                        if(!CollectionUtils.isEmpty(areaCode)){
                            importData.setCounty(areaCode.get(0).getBaseId());
                        }
                    }
                }
                if(!org.springframework.util.StringUtils.isEmpty(street)){
                    if(finalStreetMap.containsKey(street)){
                        importData.setStreet(finalStreetMap.get(street));
                    }else{
                        List<SysArea> areaCode = areaService.list(new QueryWrapper<SysArea>().likeRight("base_name", county).eq("area_level", "4").isNotNull("base_parent_id"));
                        if(!CollectionUtils.isEmpty(areaCode)){
                            importData.setStreet(areaCode.get(0).getBaseId());
                        }
                    }
                }


                BeanUtil.copyProperties(importData, activity);
                activity.setSource("0");
                activity.setCreator(userId);
                if(importData.getEnrollTime() != null){
                    activity.setStartEnrollFlag(true);
                }
                activityList.add(activity);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }
        }).sheet().doRead();
        if(!CollectionUtils.isEmpty(activityList)){
            activityInfoService.saveBatch(activityList);
        }


        return Success();
    }

    @ApiOperation("导出活动")
    @GetMapping("/export")
    public void export(HttpServletResponse response, ShowActivityInfoDto dto) {
        try {
            dto.setSource("0");
            List<String> userRoleList = managerSubService.getUserRoleList(findUserId());
            if(CollectionUtils.isEmpty(userRoleList) || !userRoleList.contains("1")){
                Message userInfo = managerSubService.getUserInfo(findUserId());
                if(userInfo != null && userInfo.getCode() == MessageCodeConstant.MSG_SUCCESS_CODE){
                    Map obj = (Map)userInfo.getObj();
                    dto.setCity(String.valueOf(obj.get("city")));
                    dto.setCounty(String.valueOf(obj.get("region")));
                    dto.setStreet(String.valueOf(obj.get("street")));
                }else{
                    throw new RuntimeException("获取用户信息有误");
                }
            }


            // 设置响应头
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("活动", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + fileName + ".xlsx\";" +
                            " filename*=UTF-8''" + fileName + ".xlsx");

            OutputStream out = response.getOutputStream();

            // 构建 ExcelWriter（整个 Excel 文件）
            ExcelWriter excelWriter = EasyExcel.write(out, ShowActivityInfoExportDto.class).build();
            // 构建 WriteSheet（具体 sheet）
            WriteSheet writeSheet = EasyExcel.writerSheet("活动").registerWriteHandler(new HeaderStyleHandler()).build();

            int pageNum = 1;
            int pageSize = 50;

            List<ShowActivityInfoVo> dataList;
            ShowActivityInfo acticityInfo = new ShowActivityInfo();
            BeanUtils.copyProperties(dto, acticityInfo);


            do {
                Page page = new Page<>(pageNum, pageSize);
                dataList = activityInfoService.listActivities(page, dto);


                if (!dataList.isEmpty()) {
                    List<ShowActivityInfoExportDto> exportList = dataList.stream().map(item -> {
                        ShowActivityInfoExportDto exportDto = new ShowActivityInfoExportDto();
                        String province = item.getProvince();
                        String city = item.getCity();
                        String county = item.getCounty();
                        BeanUtils.copyProperties(item, exportDto);
                        exportDto.setCity(city+ (StrUtil.isNotBlank(county) ? "-"+county : ""));
                        if(StrUtil.isNotBlank(item.getStreet())) {
                            exportDto.setCity(exportDto.getCity()+"-"+item.getStreet());
                        }
                        exportDto.setFirstActivityType(item.getFirstActivityType()+(!StringUtils.isEmpty(item.getSecondActivityType()) ? "-"+item.getSecondActivityType() : ""));
                        return exportDto;
                    }).collect(Collectors.toList());


                    excelWriter.write(exportList, writeSheet);
                }

                pageNum++;
            } while (!dataList.isEmpty());


            // 关闭 writer（自动关闭流）
            excelWriter.finish();

        } catch (Exception e) {
            logger.error("导出异常：", e);
            throw new RuntimeException("导出失败：" + e.getMessage());
        }
    }


    @GetMapping("/template/download")
    @ApiOperation(value = "下载模板")
    public void downloadTemplateExcel(HttpServletResponse response) {
        try {
            Resource resource = new ClassPathResource("file/活动模板.xlsx");
            response.setHeader(org.springframework.http.HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode("活动模板.xlsx", "UTF-8"));
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            IOUtils.copy(resource.getInputStream(), response.getOutputStream());
        }catch (Exception e) {
            logger.error("【下载模板异常】：{}", ExceptionUtil.stacktraceToString(e));
        }
    }

    @ApiOperation("下载活动导入模板-已废弃")
    @GetMapping("/template/download-old")
    @Deprecated
    public void downloadTemplate(HttpServletResponse response) {
        FileInputStream fileInputStream = null;
        ServletOutputStream outputStream = null;
        try {

            // 设置文件路径
            String filePath = "/home/services/template/活动导入模版.xlsx";
//            String filePath = "C:\\Users\\Administrator\\Desktop\\活动导入模版.xlsx";
            File downloadFile = new File(filePath);

            // 设置文件名（响应头中的推荐文件名）
            String fileName = "活动导入模版.xlsx";

            // 对文件名进行URL编码
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);

            // 设置文件大小
            response.setContentLength((int) downloadFile.length());

            // 通过文件输入流读取文件内容
            fileInputStream = new FileInputStream(downloadFile);

            // 通过ServletOutputStream将文件内容写入HTTP响应
            outputStream = response.getOutputStream();
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            // 关闭流资源
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            logger.error("下载活动导入模板异常：===》" + e);
        }
    }

}
